package com.xianniu.ltc.controller.general;

import cn.devezhao.commons.web.ServletUtils;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.engine.ID;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rebuild.core.Application;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.configuration.general.DataListManager;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.bizz.ZeroEntry;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.web.EntityController;
import com.rebuild.web.user.signup.LoginController;
import com.xianniu.ltc.common.*;
import com.xianniu.ltc.model.PageEntity;
import com.xianniu.ltc.model.po.*;
import com.xianniu.ltc.model.vo.*;
import com.xianniu.ltc.service.*;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * 贤牛数据列表
 *
 * @author wangruijie@xianniu.cn
 * @since 08/22/2018
 */
@Slf4j
@RestController
@RequestMapping("/xn/app/{entity}/")
public class XNGeneralListController extends EntityController {

    @Autowired
    private XnLeadService xnLeadService;
    @Autowired
    private XnLeadTeamService xnLeadTeamService;
    @Autowired
    private XnAccountService xnAccountService;
    @Autowired
    private XnAccountTeamService xnAccountTeamService;
    @Autowired
    private EquipmentApiService equipmentApiService;

    @GetMapping("list")
    public ModelAndView pageList(@PathVariable String entity,
                                 HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        final ID user = getRequestUser(request);
        String tenantCode = (String) ServletUtils.getSessionAttribute(request, LoginController.TENANT_CODE);

        final Entity useEntity = checkPageOfEntity(user, entity, response);
        if (useEntity == null) return null;

        ModelAndView mv;
        if (useEntity.getMainEntity() != null) {
            mv = createModelAndView("/general/detail-list", entity, user);
        } else {
            mv = createModelAndView("/general/record-list", entity, user);
        }

        JSON config = DataListManager.instance.getFieldsLayout(entity, user, tenantCode);
        mv.getModel().put("DataListConfig", JSON.toJSONString(config));

        // 列表相关权限
        mv.getModel().put(ZeroEntry.AllowCustomDataList.name(),
                Application.getPrivilegesManager().allow(user, ZeroEntry.AllowCustomDataList));
        mv.getModel().put(ZeroEntry.AllowDataExport.name(),
                Application.getPrivilegesManager().allow(user, ZeroEntry.AllowDataExport));
        mv.getModel().put(ZeroEntry.AllowBatchUpdate.name(),
                Application.getPrivilegesManager().allow(user, ZeroEntry.AllowBatchUpdate));

        return mv;
    }

    @PostMapping("data-list")
    public JSON dataList(@PathVariable String entity, HttpServletRequest request) {
        JSONObject query = (JSONObject) ServletUtils.getRequestJson(request);
        String tenantCode = (String) ServletUtils.getSessionAttribute(request, LoginController.TENANT_CODE);
        // 请求来源
        String requestSource = query.getString("requestSource");
        UserContextHolder.setTenant(tenantCode);
        IPage voiPage = new Page<>();
        JSONArray temArray = new JSONArray();
        boolean filterNonNull = Objects.nonNull(query.getJSONObject("filter"));
        JSONObject filterValues = null;
        if(filterNonNull){
            filterValues = query.getJSONObject("filter").getJSONObject("values");
        }
        if("lead-management".equalsIgnoreCase(requestSource)){
            log.info("后台：查询线索管理列表:{}",query);
            QueryLeadAdminPO po = new QueryLeadAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setLeadName(filterValues.getString("1"));
            }
            voiPage = xnLeadService.selectLeadForAdmin(po);
            List<XnLeadVO> temList = voiPage.getRecords();
            CleanLeadManagement co = new CleanLeadManagement<XnLeadVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("lead-fallback".equalsIgnoreCase(requestSource)){
            log.info("后台：查询线索回收站列表:{}",query);
            QueryLeadAdminPO po = new QueryLeadAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setLeadName(filterValues.getString("1"));
            }
            voiPage = xnLeadService.selectLeadFallbackForAdmin(po);
            List<XnLeadVO> temList = voiPage.getRecords();
            CleanLeadManagement co = new CleanLeadManagement<XnLeadVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("lead-team".equalsIgnoreCase(requestSource)){
            log.info("后台：查询线索组列表:{}",query);
            QueryLeadTeamAdminPO po = new QueryLeadTeamAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setTeamName(filterValues.getString("1"));
            }
            voiPage = xnLeadTeamService.selectLeadForAdmin(po);
            List<XnLeadTeamVO> temList = voiPage.getRecords();
            CleanLeadTeamManagement co = new CleanLeadTeamManagement<XnLeadTeamVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("lead-privateSea".equalsIgnoreCase(requestSource)){
            QueryLeadHighSeaPO po = new QueryLeadHighSeaPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setLeadName(filterValues.getString("1"));
            }
            log.info("前台-查询私海线索列表:{}", JSON.toJSON(po));
            voiPage = xnLeadService.selectLeadForPrivateSea(po);
            List<XnLeadVO> temList = voiPage.getRecords();
            CleanLeadPrivateSea co = new CleanLeadPrivateSea<XnLeadVO>();
            temArray = co.getObjects(entity, query, temList);
        }else if("lead-highSea".equalsIgnoreCase(requestSource)){
            QueryLeadHighSeaPO po = new QueryLeadHighSeaPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setLeadName(filterValues.getString("1"));
            }
            log.info("前台-查询公海线索列表:{}", JSON.toJSON(po));
            voiPage = xnLeadService.selectLeadForHighSea(po);
            List<XnLeadVO> temList = voiPage.getRecords();
            CleanLeadHighSea co = new CleanLeadHighSea<XnLeadVO>();
            temArray = co.getObjects(entity, query, temList);
        }else if("account-management".equalsIgnoreCase(requestSource)){
            log.info("后台：查询客户管理列表:{}",query);
            QueryAccountAdminPO po = new QueryAccountAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setAccountName(filterValues.getString("1"));
            }
            voiPage = xnAccountService.selectAccountForAdmin(po);
            List<XnAccountVO> temList = voiPage.getRecords();
            CleanAccountManagement co = new CleanAccountManagement<XnAccountVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("account-fallback".equalsIgnoreCase(requestSource)){
            log.info("后台：查询客户回收站列表:{}",query);
            QueryAccountAdminPO po = new QueryAccountAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setAccountName(filterValues.getString("1"));
            }
            voiPage = xnAccountService.selectAccountFallbackForAdmin(po);
            List<XnAccountVO> temList = voiPage.getRecords();
            CleanAccountManagement co = new CleanAccountManagement<XnAccountVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("account-team".equalsIgnoreCase(requestSource)){
            log.info("后台：查询客户组列表:{}",query);
            QueryAccountTeamAdminPO po = new QueryAccountTeamAdminPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setTeamName(filterValues.getString("1"));
            }
            voiPage = xnAccountTeamService.selectAccountTeamForAdmin(po);
            List<XnAccountTeamVO> temList = voiPage.getRecords();
            CleanAccountTeamManagement co = new CleanAccountTeamManagement<XnAccountTeamVO>();
            temArray = co.getObjects(entity, query, temList);
        } else if("account-highSea".equalsIgnoreCase(requestSource)){
            log.info("查询客户公海列表:{}",query);
            QueryAccountHighSeaPO po = new QueryAccountHighSeaPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setAccountName(filterValues.getString("1"));
            }
            voiPage = xnAccountService.selectAccountForHighSea(po);
            List<XnAccountVO> temList = voiPage.getRecords();
            CleanAccountHighSea co = new CleanAccountHighSea<XnAccountVO>();
            temArray = co.getObjects(entity, query, temList);
        }else if("account-privateSea".equalsIgnoreCase(requestSource)){
            log.info("查询客户私海列表:{}",query);
            QueryAccountHighSeaPO po = new QueryAccountHighSeaPO();
            po.setPageNum(query.getInteger("pageNo"));
            po.setPageSize(query.getInteger("pageSize"));
            if (filterNonNull && Objects.nonNull(filterValues)){
                po.setAccountName(filterValues.getString("1"));
            }
            voiPage = xnAccountService.selectAccountForPrivateSea(po);
            List<XnAccountVO> temList = voiPage.getRecords();
            CleanAccountPrivateSea co = new CleanAccountPrivateSea<XnAccountVO>();
            temArray = co.getObjects(entity, query, temList);
        }
        JSONObject result = new JSONObject();
        result.put("total", voiPage.getTotal());
        result.put("data", temArray);
        return result;
    }

    @NotNull
    private JSONArray getObjects(String entity, JSONObject query, List<ApiEquipmentVO> temList) {
        JSONArray temArray = new JSONArray();
        for(ApiEquipmentVO poolVO : temList){
            JSONArray objectArray = new JSONArray();
            JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(poolVO));
            JSONArray queryFields = query.getJSONArray("fields");
            for(String key : queryFields.toJavaList(String.class)){
                String realKey = object.keySet().stream().filter(b -> key.equalsIgnoreCase(b)).findAny().orElse(null);
                if(StrUtil.isNotBlank(realKey)){
                    objectArray.add(Objects.isNull(object.get(realKey)) ? "" : object.get(realKey));
                }else{
                    objectArray.add("");
                }
            }
            JSONObject jiegou = new JSONObject();
            jiegou.put("entity", entity);
            jiegou.put("id", poolVO.getShebeiId());
            jiegou.put("text", poolVO.getShangpinmingchengpnma());
            objectArray.add(jiegou);
            temArray.add(objectArray);
        }
        return temArray;
    }

    /**
     * 检查实体页面
     *
     * @param user
     * @param entity
     * @param response
     * @return
     * @throws IOException
     */
    static Entity checkPageOfEntity(ID user, String entity, HttpServletResponse response) throws IOException {
        if (!MetadataHelper.containsEntity(entity)) {
            response.sendError(404);
            return null;
        }

        final Entity checkEntity = MetadataHelper.getEntity(entity);
        if (!checkEntity.isQueryable()) {
            response.sendError(404);
            return null;
        }

        if (!Application.getPrivilegesManager().allowRead(user, checkEntity.getEntityCode())) {
            response.sendError(403, Language.L("YouNoPermissionAccessSome", "Page"));
            return null;
        }

        return checkEntity;
    }
}
